package ua.kharkov.khpi.tarasenko.bach.web.command.user;

import java.sql.Connection;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

import ua.kharkov.khpi.tarasenko.bach.core.Constant;
import ua.kharkov.khpi.tarasenko.bach.core.LocalizedResourceManager;
import ua.kharkov.khpi.tarasenko.bach.core.EShopException;
import ua.kharkov.khpi.tarasenko.bach.core.db.ConnectionManager;
import ua.kharkov.khpi.tarasenko.bach.core.db.DBUtils;
import ua.kharkov.khpi.tarasenko.bach.core.item.ItemBean;
import ua.kharkov.khpi.tarasenko.bach.core.user.ShoppingCart;
import ua.kharkov.khpi.tarasenko.bach.core.user.UserBean;
import ua.kharkov.khpi.tarasenko.bach.core.utils.ProductUtils;
import ua.kharkov.khpi.tarasenko.bach.dao.core.DAOFactory;
import ua.kharkov.khpi.tarasenko.bach.dao.core.item.ItemDAO;
import ua.kharkov.khpi.tarasenko.bach.dao.core.item.ItemDTO;
import ua.kharkov.khpi.tarasenko.bach.web.command.Command;

/**
 * Command to add item into cart.
 * 
 * @author oleksandr
 * 
 */
public class AddToCartCommand extends Command {
	private static final Logger log = Logger.getLogger(AddToCartCommand.class);
	private static final String ATTRIBUTE_ITEM_QUANTITY = "itemQuantity";
	private static final String ATTRIBUTE_IS_SUCCESSFULLY_ADDED = "isSuccessfullyAdded";

	@Override
	public String execute(HttpServletRequest request,
			HttpServletResponse response) throws EShopException {

		String errorMessage = null;

		// Get item id from request
		String itemIdString = request.getParameter(Constant.ATTRIBUTE_ITEM_ID);
		if (log.isTraceEnabled()) {
			log.trace("Got parameter from request "
					+ Constant.ATTRIBUTE_ITEM_ID + "=" + itemIdString);
		}

		// Create LocalizedResourceManager to get localized error messages
		LocalizedResourceManager LRManager = getLocalizedResourceManager(request);

		if ((itemIdString == null) || (itemIdString.isEmpty())) {
			errorMessage = LRManager
					.getMessage("error_message.item_id_not_spec");
		}
		int itemId = Integer.valueOf(itemIdString);

		// Get item quantity from request
		String itemQuantityString = request
				.getParameter(ATTRIBUTE_ITEM_QUANTITY);
		if (log.isTraceEnabled()) {
			log.trace("Got parameter from request " + ATTRIBUTE_ITEM_QUANTITY
					+ "=" + itemQuantityString);
		}

		if ((itemQuantityString == null) || (itemQuantityString.isEmpty())) {
			errorMessage = LRManager
					.getMessage("error_message.item_quantity_not_spec");
		}

		int itemQuantity = 0;
		try {
			itemQuantity = Integer.valueOf(itemQuantityString);

			// Validate item's quantity to order
			if (itemQuantity <= 0) {
				errorMessage = LRManager
						.getMessage("error_message.item_quantity_more_than_one");
			}
		} catch (NumberFormatException e) {
			errorMessage = LRManager
					.getMessage("error_message.item_id_not_found") + itemId;
		}

		String forward = Constant.PAGE_ADD_TO_CART_RESULT;

		// Pretty bad way but can't figure out how to do it in another way
		if (errorMessage == null) {
			Connection conn = null;
			boolean isSuccessfullyAdded = false;

			try {

				// Get ItemDTO by id
				conn = ConnectionManager.getConnection();
				ItemDAO itemDAO = DAOFactory.getDAOFactory(
						DAOFactory.DAO_TYPE.MYSQL).getItemDAO(conn);
				ItemDTO item = itemDAO.findItemById(itemId);
				if (item != null) {

					if (item.getQuantity() >= 1) {

						// Get UserBean from session
						HttpSession session = request.getSession();
						UserBean userBean = (UserBean) session
								.getAttribute(Constant.ATTRIBUTE_USER_BEAN);

						// Create ItemBean from ItemDTO
						ItemBean itemBean = ProductUtils.transformDtoToBean(item);

						// Put itemBean in user's cart
						ShoppingCart cart = userBean.getShoppingCart();
						cart.addItem(itemBean, itemQuantity);
						cart.calculateTotal();
						log.info("User with uid=" + userBean.getUserId() + " add to cart item with iid=" + itemBean.getId());
						if (log.isTraceEnabled()) {
							log.trace("User's shopping cart with id="
									+ userBean.getUserId()
									+ " now constains:\n" + cart);
						}

						isSuccessfullyAdded = true;
						request.setAttribute(ATTRIBUTE_IS_SUCCESSFULLY_ADDED,
								isSuccessfullyAdded);
						if (log.isTraceEnabled()) {
							log.trace("Set request attribute "
									+ ATTRIBUTE_IS_SUCCESSFULLY_ADDED + "="
									+ isSuccessfullyAdded);
						}
					} else {

						// If item is out of stock it can't be bought
						errorMessage = LRManager
								.getMessage("error_message.item_out_of_stock");
					}
				} else {
					errorMessage = LRManager
							.getMessage("error_message.item_out_of_stock");
				}
			} catch (EShopException e) {
				DBUtils.rollBackAndClose(conn);
				throw e;
			} finally {
				if (conn != null) {
					DBUtils.close(conn);
				}
			}
		}

		if (errorMessage != null) {
			forward = processError(request, errorMessage);
		}

		if (log.isDebugEnabled()) {
			log.debug("Forward to " + forward);
		}
		return forward;
	}
}
